package com.hsh.graph
{
	import com.hsh.acte.Actif;
	import com.hsh.txt.Champ;
	import com.hsh.txt.Etiquette;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	
	/**
	 * Objet de type Sprite
	 * @author Jean-Marie@home
	 */
	public class Visuel extends Actif
	{
		protected var _eti:Champ;
		protected var _fils:Vector.<Actif> = new Vector.<Actif>;
		protected var _sprite:Sprite = new Sprite;
		protected var _style:Style = new Style();
		protected var _forme:Forme;
		protected var _arrondi:uint = 0.0;
		
		/**
		 * Crée et affiche un visuel
		 * @param	idVisuel	identifiant
		 * @param	cible	support
		 * @param	x	gauche
		 * @param	y	haut
		 * @param	l	hargeur
		 * @param	h	hauteur
		 * @param	r	arrondi des coins
		 * @param	styl	style à appliquer au visuel
		 */
		public function Visuel(idVisuel:String, cible:*, x:Number, y:Number, l:Number, h:Number, r:Number, styl:Style, btn:Boolean = false)
		{
			super(_sprite, idVisuel);
			_forme = new Forme(this);
			cadrer(x, y, l, h, r);
			
			style = styl || _style;
			
			enModeBouton = btn;
			
			if (cible is DisplayObjectContainer)
			{
				sur(cible);
			}
			else if (cible is Visuel)
			{
				Visuel(cible).adopter(this);
			}
		}
		
		/**
		 * Ajoute un actif enfant aux actifs
		 * @param	a
		 */
		public function adopter(a:Actif, bAdopter:Boolean = true):void
		{
			if (a == null)
				return;
			if (bAdopter)
			{
				_sprite.addChild(a.diffuseur);
				if (_fils.indexOf(a) == -1)
				{
					_fils.push(a);
					a.pere = this;
				}
			}
			else
			{
				if (a.pere != this)
					return;
				_fils.splice(_fils.indexOf(a), 1);
				_sprite.removeChild(a.diffuseur);
				a.pere = null;
			}
		}
		
		override public function actualiser():void
		{
			// force le dessin
			_dessiner();
			if (_eti) _eti.actualiser();
		}
		
		/**
		 * Définit la position et la taille du visuel
		 * @param	x	gauche du visuel
		 * @param	y	haut du visuel
		 * @param	l	largeur du visuel
		 * @param	h	hauteur du visuel
		 * @param	r	arrondi (-1 : ne pas définir)
		 */
		public function cadrer(x:Number, y:Number, l:Number, h:Number, r:Number = -1):void
		{
			placer(x, y);
			tailler(l, h);
			if (r > -1)
				arrondi = r;
		}
		
		/**
		 * a. suppression des enfants b. suppression du style, de la forme
		 * c. annulation du style, de la forme, de l'arrondi, du sprite
		 * d. fermeture de l'actif
		 */
		override public function detruire():void
		{
			while (_fils.length)
			{
				_fils.pop().detruire();
			}
			_fils = null;
			
			if (_eti != null)
				_eti.detruire();
			_eti = null;
			
			_style.enlever(this);
			_style = null;
			
			_forme.detruire();
			_forme = null;
			
			_arrondi = NaN;
			_sprite = null;
			super.detruire();
		}
		
		public function etiqueter(txt:String, hAlign:Pos = null, vAlign:Pos = null):void
		{
			_eti = new Champ(this, txt, hAlign, vAlign);
		}
		
		/**
		 * Actualise le dessin si modifié
		 * @param	e
		 */
		private function _dessiner(e:Event = null):void
		{
			_forme.actualiser();
		}
		
		/**
		 * Support de la Forme
		 */
		public function get canevas():Graphics
		{
			return _sprite.graphics;
		}
		
		/**
		 * Arrondi des coins du visuel
		 */
		public function get arrondi():uint
		{
			return _arrondi;
		}
		
		public function set arrondi(value:uint):void
		{
			if (value != _arrondi)
			{
				_arrondi = value;
				_dessiner();
			}
		}
		
		/**
		 * Alpha d'arrière-plan normale
		 */
		public function get alphaFond():Number
		{
			return style.alphaFond;
		}
		
		/**
		 * Alpha de bordure
		 */
		public function get alphaBord():Number
		{
			return style.alphaBord;
		}
		
		/**
		 * Alpha du dégradé
		 */
		public function get alphaDegrade():Number
		{
			return style.alphaDegrade;
		}
		
		/**
		 * Alpha du texte
		 */
		public function get alphaTexte():Number
		{
			return style.alphaTexte;
		}
		
		/**
		 * Orientation du dégradé en degrés
		 */
		public function get angleDegr():Number
		{
			return style.angleDegr;
		}
		
		/**
		 * Couleur d'arrière-plan normale du style
		 */
		public function get coulFond():int
		{
			return style.coulFond;
		}
		
		/**
		 * Couleur de bordure du style
		 */
		public function get coulBord():int
		{
			return style.coulBord;
		}
		
		/**
		 * Couleur du dégradé du style
		 */
		public function get coulDegr():int
		{
			return style.coulDegr;
		}
		
		/**
		 * Couleur du texte du style
		 */
		public function get coulTexte():int
		{
			return style.coulTexte;
		}
		
		/**
		 * Couleur du fond survolé du style
		 */
		public function get coulSurvol():int
		{
			return style.coulSurvol;
		}
		
		/**
		 * Couleur du fond enfoncé du style
		 */
		public function get coulEnfonce():int
		{
			return style.coulEnfonce;
		}
		
		/**
		 * Couleur du fond relâché du style
		 */
		public function get coulRelache():int
		{
			return style.coulRelache;
		}
		
		/**
		 * Couleur du fond non réactif du style
		 */
		public function get coulInerte():int
		{
			return style.coulInerte;
		}
		
		/**
		 * Épaisseur de la bordure
		 */
		public function get epaisseur():Number
		{
			return style.epaisseur;
		}
		
		/**
		 * Changer le curseur de la souris au survol ?
		 */
		public function get enModeBouton():Boolean
		{
			return _sprite.buttonMode;
		}
		
		public function set enModeBouton(value:Boolean):void
		{
			_sprite.buttonMode = value;
		}
		
		/**
		 * Infos de couleurs et d'aspect du Visuel
		 */
		public function get style():Style
		{
			return _style;
		}
		
		public function set style(value:Style):void
		{
			if (_style != null && _style != value)
			{
				style.enlever(this)
			}
			_style = value;
			if (_style != null)
			{
				_style.ajouter(this);
			}
			etat = Etat.SORTIE;
		}
		
		public function get nbFils():uint
		{
			return _fils.length;
		}
		
		/**
		 * Étiquette associée au visuel
		 */
		public function get eti():Champ
		{
			return _eti;
		}
		
		public function set eti(value:Champ):void
		{
			_eti = value;
		}
	}
}